package com.java.netty.nio.netty.groupchat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Dgg
 * @Date: 2021/12/28 22:55
 */
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {

	//定义一个handler 管理所有的channel
	//GlobalEventExecutor ：全局事件执行器 是单例
	private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	//使用一个hashMap管理
//	public static Map<String, Channel> channels = new HashMap<>();

	//表示建立链接，一旦链接建立第一个被执行
	//将当前链接channel 加入到 channelGroup
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

		Channel channel = ctx.channel();

		//将该客户加入聊天信息进行推送给其他在线的客户端
		/** 该方法会将channelGroup遍历并发送消息，不需要自己遍历 */
		channelGroup.writeAndFlush("【客户端】" + channel.remoteAddress() + "加入了聊天" + simpleDateFormat.format(new Date()));
		channelGroup.add(channel);
//		channels.put("id=100", channel);
	}


	//表示断开连接，将某某客户离开推送在线所有客户
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		Channel channel = ctx.channel();
		channelGroup.writeAndFlush("【客户端】" + channel.remoteAddress() + "离开" + simpleDateFormat.format(new Date()));

		System.out.println("当前channelGroup-Size" + channelGroup.size());
	}

	//标识channel处于活动状态 提示xx上线
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println(ctx.channel().remoteAddress() + "上线了" + simpleDateFormat.format(new Date()));
	}

	//标识channel处于非活动状态 提示xx下线
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		System.out.println(ctx.channel().remoteAddress() + "离线了" + simpleDateFormat.format(new Date()));
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		//获取当前channel
		Channel channel = ctx.channel();
		//遍历channelGroup 根据不同情况推送不同消息
		channelGroup.forEach(ch -> {
			if (channel != ch) {//判断不是当前channel 直接转发消息
				ch.writeAndFlush("[客户]" + ch.remoteAddress() + "发送了消息:" + msg + simpleDateFormat.format(new Date()));
			} else {
				ch.writeAndFlush("[自己] 发送了消息" + msg + simpleDateFormat.format(new Date()));
			}
		});
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		//异常处理 ，关闭通道
		ctx.close();
	}
}
